import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  OneToMany,
  CreateDateColumn,
  UpdateDateColumn,
} from 'typeorm';
import { ApiHideProperty } from '@nestjs/swagger';
import {
  IsArray,
  IsDate,
  IsEnum,
  IsNumber,
  IsOptional,
  IsString,
  Length,
} from 'class-validator';

import {
  DietLog,
  Analytics,
  Message,
  Point,
  UserRelation,
} from '@/modules/app/entities';

export enum Gender {
  /**
   * 男性
   */
  MALE = 'MALE',
  /**
   * 女性
   */
  FEMALE = 'FEMALE',
  /**
   * 其他
   */
  OTHER = 'OTHER',
}

export enum InflammatoryTendency {
  /**
   * 抗炎饮食
   */
  ANTI_INFLAMMATORY = 'anti-inflammatory',
  /**
   * 促炎饮食
   */
  PRO_INFLAMMATORY = 'pro-inflammatory',
}

/**
 * * 用户表
 */
@Entity('users')
export class User {
  @PrimaryGeneratedColumn('increment')
  @IsNumber()
  userId: number;

  /**
   * 角色
   */
  @IsEnum(['PERSON', 'FAMILY'])
  @Column({
    type: 'enum',
    enum: ['PERSON', 'FAMILY'],
  })
  role: string;

  /**
   * 平台
   */
  @ApiHideProperty()
  @IsEnum(['ADMIN', 'APP'])
  @IsOptional()
  @Column({
    type: 'enum',
    enum: ['ADMIN', 'APP'],
    select: false,
  })
  platform?: 'ADMIN' | 'APP';

  /**
   * 手机号（登录账号）
   */
  // @Expose()
  @IsString()
  @Column({ unique: true })
  phone: string;

  /**
   * 密码（6-12位）
   */
  // @Exclude()
  @IsString()
  @Length(6, 12)
  @Column({ select: false })
  password: string;

  /**
   * 名称
   */
  @IsString()
  @Column()
  name: string;

  /**
   * 总积分
   */
  @IsNumber()
  @Column()
  totalPoint?: number = 0;

  /**
   * 性别
   */
  @IsEnum(Gender)
  @Column()
  gender: Gender;

  /**
   * 身高（厘米）
   */
  @IsNumber()
  @Column()
  height: number;

  /**
   * 体重（千克）
   */
  @IsNumber()
  @Column()
  weight: number;

  /**
   * 出生日期
   * @example yyyy-MM-dd
   */
  @IsDate()
  @Column()
  birthDate: Date;

  /**
   * 学历
   */
  @IsString()
  @Column()
  education: string;

  /**
   * 炎症倾向
   */
  @IsEnum(InflammatoryTendency)
  @Column({
    type: 'enum',
    enum: InflammatoryTendency,
    // default: InflammatoryTendency.ANTI_INFLAMMATORY,
  })
  inflammatoryTendency?: InflammatoryTendency =
    InflammatoryTendency.ANTI_INFLAMMATORY;

  /**
   * 合并症
   */
  @IsArray()
  @IsString({ each: true }) // 验证数组中的每个元素是否为字符串
  @Column({ type: 'json', nullable: true })
  comorbidities?: string[];

  /**
   * 打卡时间提醒
   */
  // ! mysql不建议用json，他会浪费空间，并且只有 mysql8 以上才支持，用 cron 比较好，待验证
  @IsArray()
  @IsString({ each: true })
  @Column({ type: 'json', nullable: true })
  reminderTimes?: string[] = [];

  /**
   * 关联用户
   */
  @OneToMany(() => UserRelation, (relation) => relation.fromUser)
  relations?: UserRelation[];

  /**
   * 被关联用户
   */
  @OneToMany(() => UserRelation, (relation) => relation.toUser)
  receivedRelations?: UserRelation[];

  /**
   * 用户打卡日志
   */
  @OneToMany(() => DietLog, (dietLog) => dietLog.user)
  dietLogs?: DietLog[];

  /**
   * 用户事件日志
   */
  @OneToMany(() => Analytics, (analytics) => analytics.user)
  analyticsEvents?: Analytics[];

  /**
   * 留言表
   */
  @OneToMany(() => Message, (message) => message.user)
  messages?: Message[];

  /**
   * 积分记录表
   */
  @OneToMany(() => Point, (message) => message.user)
  points?: Point[];

  @CreateDateColumn()
  createdAt?: Date;

  @UpdateDateColumn()
  updatedAt?: Date;

  @ApiHideProperty()
  @Column({ default: false, select: false })
  isDeleted?: boolean;

  // @Allow() // 允许额外的字段
  // [key: string]: any;
}
